package engine;

import engine.config.Config;
import engine.config.ConfigEngine;
import engine.hw.Gamepad;
import engine.hw.Keys;
import engine.hw.Pointer;
import engine.hw.RunTimer;
import engine.hw.Screen;
import engine.render.Renderer;
import engine.scene.Scene3D;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.LWJGLException;
import org.lwjgl.openal.AL;

public class ReEngine
{
    
    protected ConfigEngine configEngine;
    
    private Renderer renderer;
    private boolean running;
    
    public ReEngine()
    {
        this.configEngine = new ConfigEngine();
        this.configEngine.loadConfig("engine");
        Config configFile = this.configEngine.getConfig("engine");
        Screen.get().initialize(configFile);
        RunTimer.get().initialize();
        Keys.get().initialize();
        Pointer.get().initialize(configFile);
        Gamepad.get().initialize(configFile);
        try
        {
            AL.create();
        }
        catch (LWJGLException ex)
        {
            System.out.println(ex);
            System.exit(1);
        }
        this.renderer = new Renderer(configFile);
        this.configEngine.unloadConfig("engine");
        
        this.running = true;
    }
    
    public final void setSceneTo(Scene3D scene)
    {
        this.renderer.setSceneTo(scene);
    }
    
    public final void run()
    {
        this.onStart();
        while (this.running)
        {
            RunTimer.get().update();
            Keys.get().update();
            Pointer.get().update();
            if (Gamepad.get().isActive())
            {
                Gamepad.get().update();
            }
            
            this.perLoop();
            
            this.renderer.render();
            Screen.get().update();
            this.running = (
                !Screen.get().isCloseRequested() && 
                !Keys.get().wasPressed(Keys.ESCAPE) && 
                !Gamepad.get().wasPressed(Gamepad.BUTTON_BACK)
            );
        }
        this.onClose();
        exit();
    }
    
    private void exit() // In reverse order of construction
    {
        this.renderer.destroy();
        AL.destroy();
        Gamepad.get().destroy();
        Pointer.get().destroy();
        Keys.get().destroy();
        RunTimer.get().destroy();
        Screen.get().destroy();
        this.configEngine.destroy();
    }
    
    protected void onStart()
    {
    }
    
    protected void perLoop()
    {
    }
    
    protected void onClose()
    {
    }
    
}
